# -*- coding: utf8 -*-
#!/usr/bin/python
#
# Copyright (C) 2008 eEcho.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


"""

module description

Views which allow users to create and activate accounts.



"""

__author__ = 'sergej[A]dergatsjev[D]be (Sergej Dergatsjev)'



from django.conf import settings
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.contrib.sites.models import Site
from django.utils.safestring import SafeUnicode
from django.contrib.auth.decorators import login_required
from django.core.exceptions import ImproperlyConfigured
from django.db import models
from django.contrib.auth.models import User

from task.forms import ProfileForm, SinginForm, RegistrationForm, RegistrationProfile


import captcha



if not settings.AUTH_PROFILE_MODULE:
    raise SiteProfileNotAvailable
try:
    app_label, model_name = settings.AUTH_PROFILE_MODULE.split('.')
    Profile = models.get_model(app_label, "RegistrationProfile")
except (ImportError, ImproperlyConfigured):
    raise SiteProfileNotAvailable


def index(request, template_name='index.html', extra_context=None):
    
    if extra_context is None:
        extra_context = {}
    context = RequestContext(request)
    for key, value in extra_context.items():
        context[key] = callable(value) and value() or value
    return render_to_response(template_name,                             
                              context_instance=context)


def activate(request, activation_key,
             template_name='accounts/activate.html',
             extra_context=None):
    """
    Activate a ``User``'s account from an activation key, if their key
    is valid and hasn't expired.
    
    By default, use the template ``registration/activate.html``; to
    change this, pass the name of a template as the keyword argument
    ``template_name``.
    
    **Required arguments**
    
    ``activation_key``
       The activation key to validate and use for activating the
       ``User``.
    
    **Optional arguments**
       
    ``extra_context``
        A dictionary of variables to add to the template context. Any
        callable object in this dictionary will be called to produce
        the end result which appears in the context.
    
    ``template_name``
        A custom template to use.
    
    **Context:**
    
    ``account``
        The ``User`` object corresponding to the account, if the
        activation was successful. ``False`` if the activation was not
        successful.
    
    ``expiration_days``
        The number of days for which activation keys stay valid after
        registration.
    
    Any extra variables supplied in the ``extra_context`` argument
    (see above).
    
    **Template:**
    
    registration/activate.html or ``template_name`` keyword argument.
    
    
    function from: http://code.google.com/p/django-registration/ project
    
    """
    activation_key = activation_key.lower() # Normalize before trying anything with it.
    account = RegistrationProfile.objects.activate_user(activation_key)
    if extra_context is None:
        extra_context = {}
    context = RequestContext(request)
    for key, value in extra_context.items():
        context[key] = callable(value) and value() or value
    return render_to_response(template_name,
                              { 'account': account,
                                'site':Site.objects.get_current()},
                              context_instance=context)
    
    

def register(request, success_url=None,
             form_class=RegistrationForm, profile_callback=None,
             template_name='accounts/registration_form.html',
             extra_context=None):
    """
    Allow a new user to register an account.
    
    Following successful registration, issue a redirect; by default,
    this will be whatever URL corresponds to the named URL pattern
    ``registration_complete``, which will be
    ``/accounts/register/complete/`` if using the included URLConf. To
    change this, point that named pattern at another URL, or pass your
    preferred URL as the keyword argument ``success_url``.
    
    By default, ``registration.forms.RegistrationForm`` will be used
    as the registration form; to change this, pass a different form
    class as the ``form_class`` keyword argument. The form class you
    specify must have a method ``save`` which will create and return
    the new ``User``, and that method must accept the keyword argument
    ``profile_callback`` (see below).
    
    To enable creation of a site-specific user profile object for the
    new user, pass a function which will create the profile object as
    the keyword argument ``profile_callback``. See
    ``RegistrationManager.create_inactive_user`` in the file
    ``models.py`` for details on how to write this function.
    
    By default, use the template
    ``registration/registration_form.html``; to change this, pass the
    name of a template as the keyword argument ``template_name``.
    
    **Required arguments**
    
    None.
    
    **Optional arguments**
    
    ``form_class``
        The form class to use for registration.
    
    ``extra_context``
        A dictionary of variables to add to the template context. Any
        callable object in this dictionary will be called to produce
        the end result which appears in the context.
    
    ``profile_callback``
        A function which will be used to create a site-specific
        profile instance for the new ``User``.
    
    ``success_url``
        The URL to redirect to on successful registration.
    
    ``template_name``
        A custom template to use.
    
    **Context:**
    
    ``form``
        The registration form.
    
    Any extra variables supplied in the ``extra_context`` argument
    (see above).
    
    **Template:**
    
    registration/registration_form.html or ``template_name`` keyword
    argument.
    
    
    function from project: http://code.google.com/p/django-registration/ 
    
    is extended with reCaptcha  by Sergej Dergatsjev
    """
    
    html_captcha = None
    captcha_is_valid = True


    if request.method == 'POST':        
        if settings.EXTERNAL_RECAPTCHA:
            # Check the captcha
            check_captcha = captcha.submit(request.POST.get('recaptcha_challenge_field', None),
                                           request.POST.get('recaptcha_response_field', None),
                                           settings.RECAPTCHA_PRIVATE_KEY,
                                           request.META['REMOTE_ADDR'])
            if not check_captcha.is_valid:
                # Captcha is wrong show a error message in the template.
                captcha_is_valid = False

        form = form_class(data=request.POST, files=request.FILES)
        if form.is_valid() and captcha_is_valid:
            new_user = form.save(profile_callback=profile_callback)
            # success_url needs to be dynamically generated here; setting a
            # a default value using reverse() will cause circular-import
            # problems with the default URLConf for this application, which
            # imports this file.
            return HttpResponseRedirect(success_url or reverse('registration_complete', args=[new_user.email]))
    else:
        form = form_class()
    
    if extra_context is None:
        extra_context = {}
    context = RequestContext(request)
    for key, value in extra_context.items():
        context[key] = callable(value) and value() or value
        
    if settings.EXTERNAL_RECAPTCHA:
        # Only generate a CAPTCHA for the production site.
        html_captcha = SafeUnicode(captcha.displayhtml(settings.RECAPTCHA_PUB_KEY))

    return render_to_response(template_name,
                              { 'form': form ,
                               'html_captcha': html_captcha,
                              'captcha_is_valid': captcha_is_valid,},
                              context_instance=context)
    
    
def registration_complete(request, email,
             template_name='accounts/registration_complete.html',
             extra_context=None):
    """
    Render to response mail address associated with new_user     
    """
    
    if extra_context is None:
        extra_context = {}
    context = RequestContext(request)
    
    for key, value in extra_context.items():
        context[key] = callable(value) and value() or value
        
    return render_to_response(template_name,
                              { 'email': email,
                               'site':Site.objects.get_current(),
                                },
                              context_instance=context)
    



    
@login_required  
def edit_profiele(request, success_url=None,
             form_class=ProfileForm,             
             template_name='accounts/edit_profile.html',
             extra_context=None):
    """
    Allow a user to set Personal data of the user profile.
    
    This view will  load form to edit a user profile 
    
    **Required arguments**
    
    None.
    
    **Optional arguments**
    
    ``form_class``
        The form class to use to adapt a user profile (not auth data).
    
    ``extra_context``
        A dictionary of variables to add to the template context. Any
        callable object in this dictionary will be called to produce
        the end result which appears in the context.
    
        
    ``success_url``
        The URL to redirect to on successful editing profile.
    
    ``template_name``
        A custom template to use.
    
    **Context:**
    
    ``form``
        The registration form.
    
    Any extra variables supplied in the ``extra_context`` argument
    (see above).
    
    **Template:**
    
   
    """
    profile, created = Profile.objects.get_or_create(user=request.user)

    if request.method == "POST":
        form = ProfileForm(request.POST, instance=profile)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse("profile_edit_personal_done"))
    else:
        form = ProfileForm(instance=profile)

    
    data = {
             'section': 'personal',             
             'form': form,
           }
    return render_to_response(template_name, data, context_instance=RequestContext(request))

@login_required
def edit_profiele_done(request, success_url=None,
             form_class=ProfileForm,             
             template_name='accounts/profile_done.html',
             extra_context=None):
    """
    If a profile is adapted successful. This view will be displaying
    """
    if extra_context is None:
        extra_context = {}
        
    context = RequestContext(request)
    for key, value in extra_context.items():
        context[key] = callable(value) and value() or value
        
    return render_to_response(template_name, None, context_instance=RequestContext(request))


@login_required
def userpanel(request,
             template_name='accounts/userpanel.html',
             extra_context=None):
    """
    Main page for voting, change password, 
    profile and sing in information like user name and email.
    """
        
    data = {   # for context and extra         
             
           }
    
    if extra_context is None:
        extra_context = {}
        
    context = RequestContext(request)
    for key, value in extra_context.items():
        context[key] = callable(value) and value() or value
        
    return render_to_response(template_name, data, context_instance=RequestContext(request))

@login_required
def change_singin(request,
            form_class=SinginForm,  
            template_name='accounts/change_singin.html',
            extra_context=None):
    """
    View to change singin information, user name and email
    """
    
    
    if request.method == "POST":
        form = SinginForm(request.POST, instance=request.user)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse("userpanel"))
    else:
        form = SinginForm(instance=request.user)
        
    data = {   # for context and extra         
             'form': form,
           }
    
    if extra_context is None:
        extra_context = {}
        
    context = RequestContext(request)
    for key, value in extra_context.items():
        context[key] = callable(value) and value() or value
        
    return render_to_response(template_name, data, context_instance=RequestContext(request))

